package com.jason.rxjavatest;

import android.animation.ObjectAnimator;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.jakewharton.rxbinding.view.RxView;

import java.util.concurrent.TimeUnit;

import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.functions.Func2;
import rx.schedulers.Schedulers;

/**
 * @Author: Jason
 * @Date: 16/5/12
 * @Time: 11:18
 */

public class RxJavaTest04 extends AppCompatActivity {

    private static final String TAG = RxJavaTest04.class.getSimpleName();
    private Button btn4;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_rxjava4);

        btn4 = (Button) findViewById(R.id.btn4);
        btn4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG, "按钮点击");

            }
        });

        findViewById(R.id.bt_jump5).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(RxJavaTest04.this, RxJavaTest05.class));
            }
        });

        // 防止按钮连续点击
        RxView.clicks(btn4)
                .throttleFirst(1, TimeUnit.SECONDS)
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        Log.e(TAG, "RxView----call");
                        doOnSubscribeTest();
                    }
                });


        Observable.OnSubscribe<String> onSubscribe = new Observable.OnSubscribe<String>() {

            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("1");
                subscriber.onCompleted();
            }
        };


        Subscriber<String> subscriber = new Subscriber<String>() {
            @Override
            public void onCompleted() {
                Log.e(TAG, "-----onCompleted-----");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "-----onError-----");
            }

            @Override
            public void onNext(String s) {
                Log.e(TAG, "-----onNext-----s----->" + s);
            }
        };

        Observable.create(onSubscribe).subscribe(subscriber);


        threadTest();



    }


    public void test1() {

        Observable.OnSubscribe<String>  onSubscribe1 = new Observable.OnSubscribe<String>() {

            @Override
            public void call(Subscriber<? super String> subscriber) {

                subscriber.onNext("1");
                subscriber.onCompleted();
            }
        };

        Subscriber<Integer> subscriber1 = new Subscriber<Integer>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Integer integer) {

            }
        };


        Func1<String,Integer> transformer1 = new Func1<String, Integer>() {
            @Override
            public Integer call(String s) {
                return Integer.parseInt(s);
            }
        };

        /**
         * Func2 2代表泛型是2个参数 最后一个代表返回类型
         */
        Func2<String,String,Integer> transformer2 = new Func2<String, String, Integer>() {
            @Override
            public Integer call(String s, String s2) {
                return null;
            }
        };

        Observable.create(onSubscribe1)
                .map(transformer1)
                .subscribe(subscriber1);

    }

    /**
     * RxJava线程切换
     *
     * subscribeOn()方法的: 线程切换是发生在OnSubscribe中，即在它通知上一级OnSubscribe时,这是时间还没有开始发送。
     *                     因此subscribeOn()的线程控制可以从事件发出的开端就造成影响
     *                     Observable.create(new Observable.OnSubscribe<String>()
     *
     * observeOn()方法:  线程切换发生在它內建的Subscriber中,即发生在它即将给下一级Subscriber发送事件时,
     *                  因此observeOn()控制的是它后面的线程。
     *
     */
    public void threadTest() {

        Observable.just("1","2","3","4")
                .subscribeOn(Schedulers.io())
                .map(new Func1<String, String>() {
                    @Override
                    public String call(String s) {
                        Log.e(TAG, "map1  threadname----" + Thread.currentThread().getName() + "----threadId----->" + Thread.currentThread().getId());
                        return s;
                    }
                })
                .observeOn(Schedulers.newThread())
                .map(new Func1<String, String>() {
                    @Override
                    public String call(String s) {
                        Log.e(TAG, "map2  threadname----" + Thread.currentThread().getName() + "----threadId----->" + Thread.currentThread().getId());
                        return s;
                    }
                })
                .observeOn(Schedulers.io())
                .map(new Func1<String, String>() {
                    @Override
                    public String call(String s) {
                        Log.e(TAG, "map3  threadname----" + Thread.currentThread().getName() + "----threadId----->" + Thread.currentThread().getId());

                        return s;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.e(TAG, "map4   threadname----" + Thread.currentThread().getName() + "----threadId----->" + Thread.currentThread().getId());

                    }
                });

    }


    /**
     * doOnSubscribe
     *
     * 虽然超过一个的 subscribeOn() 对事件处理的流程没有影响，但在流程之前却是可以利用的。
       在前面讲 Subscriber 的时候，提到过 Subscriber 的 onStart() 可以用作流程开始前的初始化。
       然而 onStart() 由于在 subscribe() 发生时就被调用了，因此不能指定线程，而是只能执行在 subscribe() 被调用时的线程。
       这就导致如果 onStart() 中含有对线程有要求的代码（例如在界面上显示一个 ProgressBar，这必须在主线程执行），
       将会有线程非法的风险，因为有时你无法预测 subscribe() 将会在什么线程执行。
       而与 Subscriber.onStart() 相对应的，有一个方法 Observable.doOnSubscribe() 。
       它和 Subscriber.onStart() 同样是在 subscribe() 调用后而且在事件发送前执行，但区别在于它可以指定线程。
       默认情况下， doOnSubscribe() 执行在 subscribe() 发生的线程；而如果在 doOnSubscribe() 之后有 subscribeOn() 的话，
       它将执行在离它最近的 subscribeOn() 所指定的线程
     *
     */

    public void doOnSubscribeTest() {

        Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("doOnSubscribeTest");
                subscriber.onCompleted();
            }
        }).subscribeOn(Schedulers.io())
                .doOnSubscribe(new Action0() {
                    @Override
                    public void call() {
                        Log.e(TAG, "doOnSubscribeTest-----thread-----" + Thread.currentThread().getName());
                        ObjectAnimator.ofFloat(btn4,"translationX",0,100).setDuration(2000).start();
                        btn4.setVisibility(View.VISIBLE);

                    }
                })
                // 在 doOnSubscribe()的后面跟一个 subscribeOn() ，就能指定准备工作的线程了
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        btn4.setText(s);
                    }
                });


    }







}
